package org.example.corpus.monolingual.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.huaban.analysis.jieba.JiebaSegmenter;
import lombok.extern.slf4j.Slf4j;
import org.example.corpus.corpuscenter.service.CorpusService;
import org.example.corpus.corpuscenter.service.RedisService;
import org.example.corpus.monolingual.controller.dto.FrequencyDto;
import org.example.corpus.monolingual.service.WordFrequencyService;
import org.example.corpus.utils.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WordFrequencyServiceImpl implements WordFrequencyService {

    @Autowired
    private CorpusService corpusService;
    @Autowired
    private RedisService redisService;
    @Override
    public FrequencyDto getFrequency(String keyword, Integer corpusId) {
        String redisKey = "frequency:" + keyword + ":" + corpusId;

        // 尝试从 Redis 获取缓存数据
        FrequencyDto frequencyDto = redisService.getJson(redisKey, FrequencyDto.class);

        // 如果 Redis 中有缓存，刷新缓存过期时间并返回
        if (frequencyDto != null) {
            redisService.refreshExpire(redisKey, 3, TimeUnit.DAYS);
            return frequencyDto;
        }

        // 如果 Redis 中没有缓存，计算词频
        frequencyDto = new FrequencyDto();

        // 获取文件路径
        String filePath = corpusService.getCorpusById(corpusId).getFilePath();

        // 统计词频和总词数
        int count = 0;
        int totalCount = 0;

        try {
            // 获取文件内容
            String fileContent = FileUtil.getFileContent(filePath);

            // 清理文本并分割单词（去除非字母字符）
            String[] words = fileContent.toLowerCase().replaceAll("[^a-zA-Z ]", "").split("\\s+");
            totalCount = words.length;  // 计算清理后的词数

            // 计算特定关键词的出现次数
            count = (int) Arrays.stream(words)
                    .filter(word -> word.equalsIgnoreCase(keyword))
                    .count();

            // 计算百分比
            double percentage = totalCount == 0 ? 0 : (double) count / totalCount * 100;
            String percentageStr = String.format("%.2f%%", percentage);

            // 设置结果
            frequencyDto.setWord(keyword);
            frequencyDto.setFrequency(count);
            frequencyDto.setRange(percentageStr);

        } catch (IOException e) {
            log.error("Error reading file: ", e);
            return null; // 可以根据业务需求修改错误处理策略
        }

        // 将结果存入 Redis 并设置过期时间为 3 天
        redisService.setJsonWithExpire(redisKey, frequencyDto, 3, TimeUnit.DAYS);

        return frequencyDto;
    }




    @Override
    public List<Map<String, Object>> getFrequencyRank(int corpusId) throws IOException {
        String redisKey = "sort:" + corpusId;

        // 1. 尝试从 Redis 获取缓存数据
        List<Map<String, Object>> cachedResult = redisService.getJson(redisKey, List.class);

        if (cachedResult != null) {
            // 如果 Redis 中有缓存，直接返回缓存数据
            return cachedResult;
        }

        // 2. 如果 Redis 中没有缓存，计算词频并生成排名
        String filePath = corpusService.getCorpusById(corpusId).getFilePath();
        // 读取文件内容
        String content = FileUtil.getFileContent(filePath);

        // 清理文本并分割单词
        String[] words = content.toLowerCase().replaceAll("[^a-zA-Z ]", "").split("\\s+");

        // 使用 Map 统计单词频率
        Map<String, Integer> wordCount = new HashMap<>();
        for (String word : words) {
            wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
        }

        // 计算总词数
        int totalWords = words.length;

        // 将结果按频率降序排序
        List<Map.Entry<String, Integer>> sortedWords = wordCount.entrySet()
                .stream()
                .sorted((a, b) -> b.getValue().compareTo(a.getValue()))
                .collect(Collectors.toList());

        // 构建返回的数据列表，添加百分比
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : sortedWords) {
            Map<String, Object> wordData = new HashMap<>();
            wordData.put("word", entry.getKey());
            wordData.put("frequency", entry.getValue());

            // 计算百分比
            double percentage = (double) entry.getValue() / totalWords * 100;
            wordData.put("range", String.format("%.2f%%", percentage));

            result.add(wordData);
        }

        // 3. 将计算结果缓存到 Redis 中，设置过期时间为 7 天
        redisService.setJsonWithExpire(redisKey, result, 7, TimeUnit.DAYS);

        // 返回最终结果
        return result;
    }



}
